/* Modo d'uso: new RegisterWidget (sendFunction è la funzione da eseguire quando si preme il tasto "submit")
 poi si aggiungono i campi con addField (ID è l'id del campo, label il testo che lo descrive, params varia a seconda del tipo di campo)
 alcuni campi di params:
 - type ::= 'input' | 'pass' | 'date' | 'drop'	date è un calendario, drop un menu a tendina (default: input)
 - mandatory ::= true | false	indica se il campo è obbligatorio o no (default: false)
 - validator ::= function: ID -> String	cioè una funzione che vuole in input l'id di un elemento da validare e restituisce "Ok" se va bene, un messaggio di errore arbitrario da mostrare all'utente altrimenti
 - nel caso di type = drop c'è anche il parametro options ::= {chiave: "stringa"}, cioè un array i cui valori siano stringhe (le chiavi possono essere il cazzo che ti pare, probabilmente pure {"string1", "string2", ..., "stringn"} è accettato)
 - date accetta anche start ::= data e end ::= data che indicano la data di partenza del calendario. Purtroppo non si possono mettere date di partenza inferiori a 01/01/1900, che è quindi il default per start. Stop ha come default la data attuale (NON 13/05/2010 -_-' ovviamente)
 
 Se la widget ha ID 'asd' e viene aggiunto il campo di tipo 'type' con id 'lol' si accede al valore del campo usando $('#asd_lol_type').
 Esempio: x = new RegisterWidget('reg', null); 
 x.addField('ciao', 'Password', {type: 'pass', mandatory: true, validator: function(id){if($('#'+id).val().length < 6) return 'la password deve avere almeno 6 caratteri'; else return 'Ok'}});
 //l'utente preme submit, voglio conoscere la password:
 var userpass = $('#reg_ciao_pass').val();
 
 una volta che il server ha deciso quali sono i campi non accettabili (che ne so, nickname già in uso, numero di telefono che risulta occupato, indirizzo inesistente... Insomma, roba che non può essere controllata a lato client oppure anche controlli già fatti dal client ma che l'utente malizioso ha aggirato) chiama il metodo verify che prende in input un array {"id campo errato": "messaggio d'errore"}.
 Nel nostro esempio:
 
 //aggiungo un altro paio di campi:
 x.addField('nick', 'Nickname', {type: 'input'});
 x.addField('nomevero', 'Nome', {});
 x.addField('nascita', 'Data di nascita', {type: 'date', mandatory: true, start: '13/07/1975', end: '21/12/2012'});
 x.addField('dove', 'Nazionalità', {type: 'drop', options : {'Tunisia', 'Belize', 'Stato libero di Bananas', 'Apolide'}});
 
 // sendo i dati... nickname, nomevero e password vengono rifiutati dal server:
x.verify({'reg_nick_input': 'Il nickname scelto è da ricchione. Cambialo!', 'reg_nomevero_': "penso che l'ID sia questo se non specifico unn tipo. Meglio controllare...", 'reg_ciao_pass': 'Password troppo volgare. Vergogna!!!'});
*/

function RegisterWidget(Id, sendFunction){
    this.id = Id;
    this.param = new Param();
    this.fields = '';
    this.postRenders = new Array();
    this.mFields = new Array(); //id dei campi obbligatori
    this.validators = new Array();
    this.snd = sendFunction;
}
extend(RegisterWidget,BaseWidget);

RegisterWidget.prototype.getRenderString = function(){
  ret = '<div id="'+this.id+'" style="' + this.printInlineStyle() + '">' + this.fields + '<div id="'+this.id+'_submit"></div>';
  this.fields = null; // libero memoria
  return ret;
}

RegisterWidget.prototype.postRender = function() {
    var iter2 = IteratorArray(this.postRenders);
    try {
        var item2;
        while (iter2.hasNext()) {
            item2 = iter2.next();
            this.postRenders[item2.key]();
        }
    }
    catch (err) {
        //alert("robbaccia");
    };
/*
    for (var x in this.postRenders) {
        this.postRenders[x]();
    }*/
    this.postRenders = null; // libero memoria
    
    var f = this.mFields;
    var v = this.validators;
    
    var checkfunc = function() {
        var iter = IteratorArray(f);
        try {
            var item;
            while (iter.hasNext()) {
                item = iter.next();
                if ($('#' + item.key).val() == '') {
                    alert('campo vuoto');
                    return false;
                }
            }
        }
        catch (err) {
            if (err instanceof StopIteration);
        };
        
        var iter2 = IteratorArray(v);
        try {
            var item;
            while (iter2.hasNext()) {
                item = iter2.next();
                if ($('#' + item.key).val() != '' && $('#' + item.key + '_valid').text() != 'Ok') {
                    alert(item.key);
                    alert($('#' + item.key + '_valid').text());
                    return false;
                }
            }
        }
        catch (err) {
            if (err instanceof StopIteration);
        };
        
        return true;
    };
    var that = this;
    var submit = new ButtonWidget(this.id + '_button', function() {
        if (checkfunc()) {
            that.snd();
        }
        else
            alert('Alcuni campi non sono corretti. Verificare');
    });
    submit.setInnerText('Submit');
    submit.render(this.id + '_submit');
    $('#' + this.id + '_submit').css("position", "relative");
}

RegisterWidget.prototype.addField = function(Id, label, parameters){
	var myid = this.id+"_"+Id;
	var myid2 = myid+'_'+parameters.type;
	var externaldiv = '<div id="' + myid + '" style="' + this.printInlineStyle() + '" >';
	var lab = '<label>'+ label+':';
	if(parameters.mandatory){
		this.mFields[myid2] = myid2+"_valid";
		lab += '<span class=mandatory_symbol>*</span>';
	}
	lab += '</label><br/>';
	
	var str = this.getInternalString(myid2, label, parameters);
	if(parameters.validator instanceof Function){
		this.validators[myid2] = function(){parameters.validator(myid2)};
	} else{
		this.validators[myid2] = function(){return "Ok"};
	}
	
	this.fields += externaldiv + lab + str + '</div><br />';
	
	this.postRenders.push(function(){$('#'+myid).css("position", "relative");});
	var x = parameters.validator || V_fake;
	var m = this.mFields[myid2] || false;
	this.postRenders.push(function(){
		$('#'+myid2).blur(function(){
			var v = x(myid2);
			if(v === "Ok"){
				if(!m || $('#'+myid2).val() != ''){
					$('#'+myid2).removeClass("wrong");
					$('#'+myid2+'_valid').text(v);
				} else if (m){ //campo obbligatorio corretto ma vuoto
					$('#'+myid2).addClass("wrong");
					$('#'+myid2+'_valid').text("Campo obbligatorio!");
				}
			} else { // campo non corretto
				if(!m && $('#'+myid2).val() === ''){ // non obbligatorio e vuoto: OK
					$('#'+myid2).removeClass("wrong");
					$('#'+myid2+'_valid').text('');
				} else { // non vuoto: KO
					$('#'+myid2).addClass("wrong");
					$('#'+myid2+'_valid').text(v);
				}
			}
		})
	});
}

RegisterWidget.prototype.getInternalString = function(myid, label, parameters) {
    var str = '<span style="width:' + this.param.w + ';padding-right:5px;" >';
    switch (parameters.type) {
        case "drop":
            str += '<select name="' + label + '" id="' + myid + '"><option></option>';
            var iter = IteratorArray(parameters.options);
            try {
                while (iter.hasNext())
                    str += '<option>' + (iter.next()).value + '</option>';
            }
            catch (err) {
                if (err instanceof StopIteration);
            };
            
            str += '</select>';
            break;
        case "pass":
            str += '<input id="' + myid + '" type="password" />';
            break;
        case "date":
            var def = parameters.show || '-25y';
            var st = parameters.start || '-50y';
            var en = parameters.end || '+0';
            this.postRenders.push(function() {
                $('#' + myid).datepicker({
                   defaultDate: def,
                   minDate: st,
                   maxDate: en,
                   beforeShow: function(){$('#'+myid).val('')}
                })
            });
            str += '<input id="' + myid + '" type="text" readonly="readonly" />';
            break;
        case "input":
        default:
            str += '<input id="' + myid + '" type="text" />';
    }
    str += '<div id="' + myid + '_valid" style="display:inline-block, background-color:inherit, position:static"></div>';
    return str + '</span>';
}

RegisterWidget.prototype.verify = function(errors){
	for(var x in errors){
		$('#'+x).addClass('wrong');
		$('#'+x+'_valid').text(errors[x]);
	}
}

var P_input = {
	mandatory: true,
	type: "input",
	validator: function(){return "Ok";}
};

var P_pass = {
	mandatory: true,
	type: "pass",
	validator: ""//aggiungere validatore serio di default
}

var V_fake = function(){return "Ok";};
var V_never = function(){return "Failure";};

$.datepicker.setDefaults({
		closeText: 'Chiudi',
		prevText: '&#x3c;Prec',
		nextText: 'Succ&#x3e;',
		currentText: 'Oggi',
		monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
			'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
		monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
			'Lug','Ago','Set','Ott','Nov','Dic'],
		dayNames: ['Domenica','Luned&#236','Marted&#236','Mercoled&#236','Gioved&#236','Venerd&#236','Sabato'],
		dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
		dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'],
		weekHeader: 'Sm',
		dateFormat: 'dd/mm/yy',
		firstDay: 1,
		isRTL: false,
		showMonthAfterYear: false,
		yearSuffix: '',
      showOn: 'button',
      buttonImageOnly: true,
      buttonImage: 'images/icon_cal.png',
      showOtherMonths: true,
      changeMonth: true,
      changeYear: true,
      showButtonPanel: true
   });
